package HuginnDaemon;
use strict;
use warnings;
use POSIX qw(setsid strftime);
use Sys::Syslog qw(:standard :macros);
use HuginnConfiguration qw( %Config );
use HuginnCommunications qw( SendFax SendEmail SendSMS SendToLogFile LoadMainLoopDb LoadMainStatus);
use HuginnDatabase qw( RowRotate DatabaseOpen ForEachRowToSend DatabaseClose SetRowSent SetRowError);
use feature 'switch';
require Exporter;
our @ISA = qw(Exporter);
our @EXPORT_OK = qw( IsRunning Terminate DaemonComunication Daemonize DaemonName MainDaemon MainDaemonPhp MainDaemonStatusPhp);

sub GetPidByName
{
    my $pcname= $_[0] || "$0";
    substr($pcname,0,1)="[".substr($pcname,0,1)."]";
    my $cmd = "ps aux | grep \"" .$pcname. "\" | gawk '{ print \$2}'";
    my $pid = `$cmd`;
    return $pid;
}
sub IsRunning
{
    return GetPidByName($_[0] || "$0");
}
sub DaemonComunication
{
    my $pcname = $_[0] || "$0";
    my $signal = $_[1] || 12;
    Terminate($pcname,$signal);
}
sub Terminate
{
    my $pcname = $_[0] || "$0";
    my $signal = $_[1] || 12;
    kill $signal, GetPidByName($pcname) if IsRunning($pcname);
    foreach (1..10)
    {
        return unless IsRunning($pcname);
        sleep 1;
    }
}
sub Daemonize
{
    my $body = shift || \&die;
    chdir '/'                 or die "Can't chdir to /: $!";
    umask 0;
    #open STDIN, '/dev/null'   or die "Can't read /dev/null: $!";
    #open STDOUT, '>/dev/null' or die "Can't write to /dev/null: $!";
    #open STDERR, '>/dev/null' or die "Can't write to /dev/null: $!";
    defined(my $pid = fork)   or die "Can't fork: $!";
    return if $pid;
    setsid or die "Can't start a new session: $!";
    $body->();
 }   
sub DaemonName
{
    #my $daemon = shift;
    #given($daemon)
    #{
    #    when ($Config{DAEMON_NAME_PHP})	{return $Config{DAEMON_NAME_PHP};}
    #    default        			{return $Config{DAEMON_NAME};}
    #}
    return $Config{DAEMON_NAME};
}
sub MainDaemon()
{
    $0 = $Config{DAEMON_NAME};

    openlog($Config{DAEMON_NAME}, 'ndelay,pid', 'user') or warn "Unable to activate logging";
    $Huginn::WakeUp = 0;
    $Huginn::ShouldExit = 0;
    
    &RegisterHandler();
    &Log('info',"Started");
    while (!$Huginn::ShouldExit)
    {
        eval
        {
            DatabaseOpen();
            ForEachRowToSend(\&DoYourJob);
            RowRotate();
        };
        &Log('err',$@) if $@;

        $Huginn::WakeUp = 0;
        alarm $Config{TIME_BETWEEN_POOLING};
        while(!$Huginn::WakeUp)
        {
            sleep 1;
        }
    }
    &Log('info',"Halted");
    closelog();
}
sub DoYourJob
{
     my ($Id,$Destination,$Kind,$Message,$path_archivio) = @_;

     my $Commiter = \&SetRowSent;
     my $sender;
     
     given($Kind)
     {
        when("fax"  )   {$sender = \&SendFax;}
        when("sms"  )   {$sender = \&SendSMS;}
        when("email")   {$sender = \&SendEmail;}
	when("logfile") {$sender = \&SendToLogFile;}
     }
     eval{ $sender->($Destination, $Message,$path_archivio);};
     my $message = $@;
     $Commiter = \&SetRowError if $message;
     $Commiter->($Id,$message,$path_archivio);
}

sub RegisterHandler()
{
    $SIG{USR1} = \&WakeUp;
    $SIG{USR2} = \&WakeUpAndExit;
    $SIG{ALRM} = \&WakeUp;
}
sub WakeUp()
{
    $Huginn::WakeUp = 1;   
}
sub WakeUpAndExit()
{
    $Huginn::ShouldExit = 1;
    WakeUp();
}
sub Log()
{
    my ($level,@msg)=@_;
    syslog($level,@msg);
}
sub MainDaemonPhp()
{
    $0 = $Config{DAEMON_NAME_PHP};

    openlog($Config{DAEMON_NAME_PHP}, 'ndelay,pid', 'user') or warn "Unable to activate logging";
    $Huginn::WakeUp = 0;
    $Huginn::ShouldExit = 0;
    
    &RegisterHandler();
    &Log('info',"Started");
    while (!$Huginn::ShouldExit)
    {
        eval
        {
            &LoadMainLoopDb;
        };
        &Log('err',$@) if $@;

        $Huginn::WakeUp = 0;
        alarm $Config{TIME_BETWEEN_POOLING_PHP};
        while(!$Huginn::WakeUp)
        {
            sleep 1;
        }
    }
    &Log('info',"Halted");
    closelog();
}
sub MainDaemonStatusPhp()
{
    $0 = $Config{DAEMON_STATUS_PHP};

    openlog($Config{DAEMON_STATUS_PHP}, 'ndelay,pid', 'user') or warn "Unable to activate logging";
    $Huginn::WakeUp = 0;
    $Huginn::ShouldExit = 0;
    
    &RegisterHandler();
    &Log('info',"Started");
    while (!$Huginn::ShouldExit)
    {
        eval
        {
            &LoadMainStatus;
        };
        &Log('err',$@) if $@;

        $Huginn::WakeUp = 0;
        alarm $Config{TIME_BETWEEN_POOLING_PHP_STATUS};
        while(!$Huginn::WakeUp)
        {
            sleep 1;
        }
    }
    &Log('info',"Halted");
    closelog();
}
1;
